package com.example.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.common.dto.PurchaseDTO;
import com.example.domain.Commodity;
import com.example.domain.Purchase;
import com.example.domain.User;
import com.example.domain.WalletRecord;
import com.example.service.CommodityService;
import com.example.service.PurchaseService;
import com.example.service.UserService;
import com.example.service.WalletRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class OrderController {

	private final PurchaseService purchaseService;

	private final CommodityService commodityService;

	private final UserService userService;

	private final WalletRecordService walletRecordService;

	@Autowired
	public OrderController(PurchaseService purchaseService, CommodityService commodityService,
	                       UserService userService, WalletRecordService walletRecordService) {
		this.purchaseService = purchaseService;
		this.commodityService = commodityService;
		this.userService = userService;
		this.walletRecordService = walletRecordService;
	}

	/**
	 * 综合处理用户购买商品
	 *
	 * @return 返回JSON字符串
	 */
	@PostMapping(value = "/user/purchase", produces = "application/json;charset=utf-8")
	public String buyCommodity(@RequestBody PurchaseDTO purchaseDTO) {
		Map<String, Object> message = new HashMap<>(16);

		Commodity commodity = commodityService.getById(purchaseDTO.getCommodityId());
		if (commodity.getSaleCount() < purchaseDTO.getPurchaseCount()) {
			message.put("information", 0);
		} else {
			//新增订单记录
			this.insertPurchase(commodity, purchaseDTO.getUserId(), purchaseDTO.getPurchaseCount(), 0, purchaseDTO.getDelivery());

			message.put("information", 1);
		}
		System.out.println(purchaseDTO);
		return JSON.toJSONString(message);
	}

	/**
	 * 将商品添加至购物车
	 *
	 * @param userId      购买商品的用户id
	 * @param commodityId 商品id
	 * @param num         添加至购物车中商品的数量
	 * @return 返回JSON字符串
	 */
	@PostMapping(value = "/user/cart/add", produces = "application/json;charset=utf-8")
	public String addToCart(Integer userId, Integer commodityId, Integer num, Double delivery) {
		Map<String, Object> message = new HashMap<>(16);

		//获取要添加到购物车的商品
		Commodity commodity = commodityService.getById(commodityId);

		//新增订单记录
		this.insertPurchase(commodity, userId, num, 1, delivery);

		message.put("message", 1);

		return JSON.toJSONString(message);
	}

	/**
	 * 综合处理用户在购物车中下单一个商品
	 *
	 * @return 返回JSON字符串
	 */
	@PostMapping(value = "/user/cart/purchase", produces = "application/json;charset=utf-8")
	public String buyCommodityInCart(@RequestBody List<PurchaseDTO> list) {
		Map<String, Object> message = new HashMap<>(16);
		for (PurchaseDTO purchaseDTO : list) {
			Purchase purchase = purchaseService.getById(purchaseDTO.getId());
			Commodity commodity = commodityService.getById(purchase.getCommodityId());
			if (commodity.getSaleCount() < purchaseDTO.getPurchaseCount()) {
				message.put("information", 0);
				message.put("text", commodity.getText());
				break;
			}
		}
		if (!message.containsKey("information")) {
			//修改订单信息
			for (PurchaseDTO purchaseDTO : list) {
				Purchase purchase = purchaseService.getById(purchaseDTO.getId());

				purchase.setPurchaseCount(purchaseDTO.getPurchaseCount());
				purchase.setDelivery(purchaseDTO.getDelivery());
				purchase.setIsShopping(0);
				purchaseService.updateById(purchase);
			}
			message.put("information", 1);
		}

		return JSON.toJSONString(message);
	}

	/**
	 * 获取用户购物车中的订单
	 *
	 * @param userId 用户id
	 * @return 返回查询到的订单信息
	 */
	@PostMapping(value = "/user/cart/all", produces = "application/json;charset=utf-8")
	public String selectCart(Integer userId, Integer currentPage, Integer pageSize) {
		PurchaseDTO purchaseDTO = new PurchaseDTO();
		purchaseDTO.setUserId(userId).setIsShopping(1).setCurrentPage(currentPage).setPageSize(pageSize);

		//条件分页查询
		Page<Purchase> page = purchaseService.getPurchaseByCondition(purchaseDTO);
		return this.getCartInfo(page);
	}

	/**
	 * 删除购物车中的一个记录
	 *
	 * @param purchaseId 订单信息
	 * @return
	 */
	@PostMapping(value = "/user/cart/delete/one", produces = "application/json;charset=utf-8")
	public String selectCart(Integer purchaseId) {
		Map<String, Object> message = new HashMap<>(16);

		boolean b = purchaseService.removeById(purchaseId);
		message.put("delete", 1);

		return JSON.toJSONString(message);
	}

	/**
	 * 查询用户购买记录
	 *
	 * @param userId 用户id
	 * @return 返回用户的购买记录
	 */
	@PostMapping(value = "/user/purchase/all", produces = "application/json;charset=utf-8")
	public String selectBuyHistory(Integer userId, Integer currentPage, Integer pageSize) {
		PurchaseDTO purchaseDTO = new PurchaseDTO();
		purchaseDTO.setUserId(userId).setIsShopping(0).setCurrentPage(currentPage).setPageSize(pageSize);
		Page<Purchase> page = purchaseService.getPurchaseByCondition(purchaseDTO);
		return this.getUserRecordInfo(page);
	}

	/**
	 * 查询商家订单记录
	 *
	 * @param merchantId 商家id
	 * @return 返回查询记录
	 */
	@PostMapping(value = "/merchant/purchase/all", produces = "application/json;charset=utf-8")
	public String selectSaleHistory(Integer merchantId, Integer currentPage, Integer pageSize) {
		PurchaseDTO purchaseDTO = new PurchaseDTO();
		purchaseDTO.setMerchantId(merchantId).setIsShopping(0).setCurrentPage(currentPage).setPageSize(pageSize);
		Page<Purchase> page = purchaseService.getPurchaseByCondition(purchaseDTO);
		return this.getMerchantRecordInfo(page);
	}

	/**
	 * 用户确定收取餐品确认订单
	 *
	 * @param id
	 * @param orderState
	 * @return
	 */
	@PostMapping(value = "/user/purchase/confirm/state", produces = "application/json;charset=utf-8")
	public String confirmPurchase(Integer id, Integer orderState) {
		Map<String, Object> message = new HashMap<>(16);
		Purchase purchase = purchaseService.getById(id);
		purchase.setOrderState(orderState);
		purchaseService.updateById(purchase);
		User merchant = userService.getById(purchase.getMerchantId());
		User rider = userService.getById(purchase.getRiderId());
		Commodity commodity = commodityService.getById(purchase.getCommodityId());

		//计算商家应收款数
		double totalPrice = purchase.getPurchaseCount() * commodity.getPrice() * (100 - merchant.getRate()) / 100;
		WalletRecord merchantWallet = new WalletRecord();
		merchantWallet.setMoney(totalPrice);
		merchantWallet.setIdentity(2);
		merchantWallet.setUserId(purchase.getMerchantId());

		WalletRecord riderWallet = new WalletRecord();
		riderWallet.setMoney(purchase.getDelivery());
		riderWallet.setIdentity(2);
		riderWallet.setUserId(purchase.getRiderId());

		//增加金额交易记录
		walletRecordService.save(merchantWallet);
		walletRecordService.save(riderWallet);

		//用户确认订单后，更新商品的信息
		this.updateCommodityInfo(commodity, purchase.getPurchaseCount());

		merchant.setBalance(merchant.getBalance() + totalPrice);
		rider.setBalance(rider.getBalance() + purchase.getDelivery());

		//修改商家和骑手的账户余额
		userService.updateById(merchant);
		userService.updateById(rider);

		message.put("message", 1);
		message.put("wallet", 1);

		return JSON.toJSONString(message);
	}

	/**
	 * 查询配送员的所有订单
	 *
	 * @param riderId
	 * @param currentPage
	 * @param pageSize
	 * @return
	 */
	@PostMapping(value = "/rider/purchase/all", produces = "application/json;charset=utf-8")
	public String getPurchaseForRider(Integer riderId, Integer currentPage, Integer pageSize) {
		PurchaseDTO purchaseDTO = new PurchaseDTO();
		purchaseDTO.setRiderId(riderId).setOrderState(0).setIsShopping(0).setCurrentPage(currentPage).setPageSize(pageSize);
		Page<Purchase> page = purchaseService.getPurchaseByCondition(purchaseDTO);
		return this.getRiderRecordInfo(page);
	}

	/**
	 * 修改订单状态
	 *
	 * @return
	 */
	@PostMapping(value = "/rider/purchase/update/state", produces = "application/json;charset=utf-8")
	public String updateOrderState(Integer id, Integer riderId, Integer orderState) {
		Map<String, Object> message = new HashMap<>(16);
		Purchase purchase = purchaseService.getById(id);
		if (orderState == 1) {
			purchase.setRiderId(riderId);
		} else if (orderState == 3) {
			Commodity commodity = commodityService.getById(purchase.getCommodityId());
			commodity.setSaleCount(commodity.getSaleCount() - purchase.getPurchaseCount());
			commodityService.updateById(commodity);
		}
		purchase.setOrderState(orderState);
		purchaseService.updateById(purchase);
		message.put("message", 1);
		return JSON.toJSONString(message);
	}

	/**
	 * 在支付时更新商品信息
	 */
	private void updateCommodityInfo(Commodity commodity, Integer num) {
		commodity.setHistoricalSaleCount(commodity.getHistoricalSaleCount() + num);
		commodity.setPeopleBuy(commodity.getPeopleBuy() + 1);
		commodity.setTradingCount(commodity.getTradingCount() + num);
		commodityService.updateById(commodity);
	}

	/**
	 * 新增订单信息
	 */
	private void insertPurchase(Commodity commodity, Integer userId, Integer num, Integer isShopping, Double delivery) {
		Purchase purchase = new Purchase();
		purchase.setPurchaseCount(num);
		purchase.setUserId(userId);
		purchase.setCommodityId(commodity.getId());
		purchase.setMerchantId(commodity.getUserId());
		purchase.setDelivery(delivery);
		purchase.setOrderState(0);
		purchase.setIsShopping(isShopping);

		purchaseService.save(purchase);
	}

	/**
	 * 返回购物车中所需信息
	 */
	private String getCartInfo(Page<Purchase> page) {
		Map<String, Object> message = new HashMap<>(16);
		List<Map<String, Object>> result = new ArrayList<>();
		for (Purchase purchase : page.getRecords()) {
			Map<String, Object> map = new HashMap<>(16);
			Commodity commodity = commodityService.getById(purchase.getCommodityId());
			map.put("id", purchase.getId());
			map.put("picture", commodity.getPicture());
			map.put("text", commodity.getText());
			map.put("type", commodity.getType());
			map.put("price", commodity.getPrice());
			map.put("saleCount", commodity.getSaleCount());
			map.put("historicalSaleCount", commodity.getHistoricalSaleCount());
			map.put("productState", commodity.getProductState());
			map.put("purchaseCount", purchase.getPurchaseCount());
			map.put("totalPrice", purchase.getPurchaseCount() * commodity.getPrice());
			map.put("gmtCreate", purchase.getGmtCreate());
			map.put("orderState", purchase.getOrderState());
			result.add(map);
		}
		message.put("message", result);
		message.put("total", page.getTotal());
		return JSON.toJSONString(message);
	}

	/**
	 * 返回用户购买记录信息
	 */
	private String getUserRecordInfo(Page<Purchase> page) {
		Map<String, Object> message = new HashMap<>(16);
		List<Map<String, Object>> result = new ArrayList<>();
		for (Purchase purchase : page.getRecords()) {
			Map<String, Object> map = new HashMap<>(16);
			Commodity commodity = commodityService.getById(purchase.getCommodityId());
			map.put("id", purchase.getId());
			map.put("userId", purchase.getUserId());
			map.put("commodityId", purchase.getCommodityId());
			map.put("gmtCreate", purchase.getGmtCreate());
			map.put("text", commodity.getText());
			map.put("type", commodity.getType());
			map.put("purchaseCount", purchase.getPurchaseCount());
			map.put("orderState", purchase.getOrderState());
			map.put("totalPrice", purchase.getPurchaseCount() * commodity.getPrice());
			map.put("delivery", purchase.getDelivery());
			map.put("tradingState", purchase.getOrderState());
			map.put("gmtUpdate", purchase.getGmtUpdate());
			result.add(map);
		}
		message.put("information", result);
		message.put("total", page.getTotal());
		return JSON.toJSONString(message);
	}

	/**
	 * 返回商家售卖记录信息
	 */
	private String getMerchantRecordInfo(Page<Purchase> page) {
		Map<String, Object> message = new HashMap<>(16);
		List<Map<String, Object>> result = new ArrayList<>();
		for (Purchase purchase : page.getRecords()) {
			Map<String, Object> map = new HashMap<>(16);
			User user = userService.getById(purchase.getUserId());
			Commodity commodity = commodityService.getById(purchase.getCommodityId());
			map.put("userName", user.getUserName());
			map.put("text", commodity.getText());
			map.put("price", commodity.getPrice());
			map.put("purchaseCount", purchase.getPurchaseCount());
			map.put("gmtCreate", purchase.getGmtCreate());
			map.put("orderState", purchase.getOrderState());
			result.add(map);
		}
		message.put("information", result);
		message.put("total", page.getTotal());
		return JSON.toJSONString(message);
	}

	/**
	 * 返回骑手订单信息
	 */
	private String getRiderRecordInfo(Page<Purchase> page) {
		Map<String, Object> message = new HashMap<>(16);
		List<Map<String, Object>> result = new ArrayList<>();
		for (Purchase purchase : page.getRecords()) {
			Map<String, Object> map = new HashMap<>(16);
			User user = userService.getById(purchase.getUserId());
			Commodity commodity = commodityService.getById(purchase.getCommodityId());
			map.put("id", purchase.getId());
			map.put("userName", user.getUserName());
			map.put("text", commodity.getText());
			map.put("price", commodity.getPrice());
			map.put("purchaseCount", purchase.getPurchaseCount());
			map.put("gmtCreate", purchase.getGmtCreate());
			map.put("orderState", purchase.getOrderState());
			result.add(map);
		}
		message.put("information", result);
		message.put("total", page.getTotal());
		return JSON.toJSONString(message);
	}

}
